{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5.逻辑回归\n",
    "## 调包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.1.训练算法：使用梯度上升找到最佳参数\n",
    "### 5.1.1.读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def loadDataSet():\n",
    "    \"\"\"\n",
    "    读取数据集\n",
    "    参数：\n",
    "        无\n",
    "    返回：\n",
    "        dataMat -- 数据矩阵\n",
    "        labelMat -- 标签矩阵\n",
    "    \"\"\"\n",
    "    #初始化两个矩阵\n",
    "    dataMat = []; labelMat = []\n",
    "    #打开测试文件\n",
    "    fr = open('testSet.txt')\n",
    "    #读取每一行\n",
    "    for line in fr.readlines():\n",
    "        #分割\n",
    "        lineArr = line.strip().split()\n",
    "        #添加到数据矩阵\n",
    "        dataMat.append([1.0, np.float(lineArr[0]), np.float(lineArr[1])])\n",
    "        #添加到标签矩阵\n",
    "        labelMat.append(np.int(lineArr[2]))\n",
    "    return dataMat,labelMat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.1.2.sigmoid函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def sigmoid(inX):\n",
    "    return 1.0 / (1 + np.exp(-inX))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.1.3.梯度上升函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def gradAscent(dataMatIn, classLabels):\n",
    "    \"\"\"\n",
    "    梯度上升函数\n",
    "    参数：\n",
    "        dataMatIn -- 输入数据矩阵\n",
    "        classLabels -- 类标签\n",
    "    返回：\n",
    "        weights -- 权重参数\n",
    "    \"\"\"\n",
    "    #转化为np矩阵\n",
    "    dataMatrix = np.array(dataMatIn)\n",
    "    labelMat = np.array(classLabels).reshape(-1, 1)\n",
    "    #得到数据矩阵维度，分别为样本数和特征数\n",
    "    m,n = dataMatrix.shape\n",
    "    #学习率\n",
    "    alpha = 0.001\n",
    "    #最大迭代次数\n",
    "    maxCycles = 500\n",
    "    #初始化参数\n",
    "    weights = np.ones((n,1))\n",
    "    #迭代\n",
    "    for k in range(maxCycles):\n",
    "        #预测值\n",
    "        h = sigmoid(np.dot(dataMatrix,weights))\n",
    "        #误差\n",
    "        error = (labelMat - h)\n",
    "        #更新参数\n",
    "        weights = weights + alpha * np.dot(dataMatrix.T, error)\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "学习到的权重为[[ 4.12414349]\n",
      " [ 0.48007329]\n",
      " [-0.6168482 ]]\n"
     ]
    }
   ],
   "source": [
    "dataArr, labelMat = loadDataSet()\n",
    "weights = gradAscent(dataArr, labelMat)\n",
    "print(\"学习到的权重为{}\".format(weights))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.2.分析数据：画出决策边界 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def plotBestFit(weights):\n",
    "    \"\"\"\n",
    "    画出决策边界\n",
    "    参数：\n",
    "        weights -- 权重参数\n",
    "    返回：\n",
    "        无 -- 直接画图\n",
    "    \"\"\"\n",
    "    #读取数据\n",
    "    dataMat,labelMat=loadDataSet()\n",
    "    #数据矩阵\n",
    "    dataArr = np.array(dataMat)\n",
    "    #得到数据点的个数\n",
    "    n = dataArr.shape[0]\n",
    "    #不同类别的数据的横纵坐标记录列表\n",
    "    xcord1 = []; ycord1 = []\n",
    "    xcord2 = []; ycord2 = []\n",
    "    #遍历数据点\n",
    "    for i in range(n):\n",
    "        if np.int(labelMat[i])== 1:\n",
    "            xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])\n",
    "        else:\n",
    "            xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])\n",
    "    #新建画布\n",
    "    fig = plt.figure()\n",
    "    #新建轴\n",
    "    ax = fig.add_subplot(111)\n",
    "    #绘制类型1的散点图\n",
    "    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')\n",
    "    #绘制类型0的散点图\n",
    "    ax.scatter(xcord2, ycord2, s=30, c='green')\n",
    "    #绘制决策边界\n",
    "    #x取值范围\n",
    "    x = np.arange(-3.0, 3.0, 0.1)\n",
    "    #按照学习的权重求y=-(w0+w1*x)/w2\n",
    "    y = (-weights[0]-weights[1]*x)/weights[2]\n",
    "    #绘制决策直线\n",
    "    ax.plot(x, y)\n",
    "    #轴标记文本\n",
    "    plt.xlabel('X1'); plt.ylabel('X2')\n",
    "    #显示\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEKCAYAAAAFJbKyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xlw3Ged5/H3V5Kv2GonxkdkW46dxMRWyAExcpZwhApk\nHA9LmB12JhkCy7GxTUEWdmG9HMUxUNQwBmaYCUfibFLAkIFlCwgUOEAIbAUo4tgOdg4fYOwksq34\nSGId8aXju390S261ulv9k/rXv6M/ryqV1D/9uvVttfT79vM83+d5zN0RERGpVEPUAYiISLIocYiI\nSCBKHCIiEogSh4iIBKLEISIigShxiIhIIEocIiISiBKHiIgEosQhIiKBNEUdQBhmz57tixcvjjoM\nEZHE2LZt2zF3n1PJualMHIsXL2br1q1RhyEikhhm9nSl56qrSkREAlHiEBGRQJQ4REQkkNATh5nd\nY2ZHzOyJvGOfNrODZrY997G6xH1XmdkeM9trZh8JO1YRERlbLVoc3wBWFTn+z+5+Ze5jU+E3zawR\n+CpwA9AG3GxmbaFGKiIiYwo9cbj7Q8Dz47hrO7DX3fe5+xngu8CNVQ1OREQCi3KM4zYzeyzXlXVe\nke8vADrybh/IHRMRkQhFlTi+DlwIXAl0Al+a6AOa2Roz22pmW48ePTrRhxNJvI6uDm7bdBvtd7Vz\n26bb6OjqGPtOIhWIZAKgux8e+trM7gJ+UuS0g0Br3u2FuWOlHnMjsBFgxYoV2khd6lpHVwdX3HEF\nvWd66RvsY/uz27n38XvZsW4HrTNbx34AkTIiaXGYWUvezb8Cnihy2hZgqZktMbPJwE3Aj2sRn0jS\nbfjdhuGkAdA32EfvmV42/G5DxJFJGoTe4jCz7wDXArPN7ADwKeBaM7sScOApYG3u3PnA/3b31e7e\nb2bvB34ONAL3uPuTYccrkgabD24eThpD+gb7eOTgIxFFJGkSeuJw95uLHL67xLmHgNV5tzcBo0p1\nRaS8lQtWsv3Z7SOSx6SGSbQvaI8wKkkLzRwXSaH116xnxuQZTGqYBGSTxozJM1h/zfqII5M0UOIQ\nSaHWma3sWLeDtVetpX1+O2uvWquBcamaVC6rLpIWHV0dbPjdBjYf3MzKBStZf836ii/+rTNbuX31\n7SFHKPVIiUMkplRSK3GlriqRmFJJrcSVEodITKmkVuJKiUMkRvKXCTnVf4omG9mbHJeSWi1nUt80\nxiESE4VjGk0NTQz4AE3WRL/3x6akVmMvohaHSEwUjmn0D/bT1NDE8jnLY1VSq7EXUYtDJCZKjWlM\na5rG5ls3RxTVaBp7EbU4RGJi5YKVwzO9h8RlTCNfUuKU8ChxiMREUpYJSUqcEh4lDpGYSMoyIbWI\nU1Vb8Wbu6dvzaMWKFb5169aowxCRcSis2hpq0cQxiaaJmW1z9xWVnKsWh4jEiqq24k+JQ0RiRVVb\n8afEISKxoqqt+FPiEJGiohqgDrNqS4Pu1aHBcREZJeoB6qF9SH7zzG8Y9EEarIHXLHpNoP1Iij2m\nBt1Li9XguJndY2ZHzOyJvGNfMLPdZvaYmf3QzM4tcd+nzOxxM9tuZsoEIjUS9QB168xW1l+znme6\nnmH3sd3sOLyDO7fdyRV3XDHuVkLUzylNatFV9Q1gVcGxB4CXufvlwB+Bj5a5/+vd/cpKM6GIjDSe\n7pk4DFBX+0Ifh+eUFqEnDnd/CHi+4Ngv3L0/d/NhYGHYcYjUo6HumTu33cmWQ1sqftcehwHqal/o\n4/Cc0iIOg+PvBu4v8T0Hfmlm28xsTbkHMbM1ZrbVzLYePXq06kGKJNEnfvUJjp86HvhdexyWFan2\nhT4OzyktIk0cZvZxoB+4t8Qpr3b3K4EbgPeZ2WtLPZa7b3T3Fe6+Ys6cOSFEK2FTxUt1dXR18O3H\nv40zsgCmknftcVj+pNoX+jg8p7SoSVWVmS0GfuLuL8s79k5gLXCdu5+o4DE+DfS6+xfHOldVVcmj\nipfqu23TbXxty9cYZHDEccN4x+XvoHlKM5sPbmblgpUTqlYK01B11SMHH6F9QXts40yDIFVVkezH\nYWargPXA60olDTObDjS4e0/u6+uBz9QwTKmhcgOht6++PeLokmnzwc2jkgZkE8d9e+7jRN+J2O/g\n1zqzVa9/DNWiHPc7wO+BS8zsgJm9B/gK0Aw8kCu1vSN37nwz25S76zzgt2a2A3gE+Km7/yzseCUa\nqnipvmJjBA00sPQlS4eTBqgsVYILvcXh7jcXOXx3iXMPAatzX+8DrggxNImRlQtWsv3Z7SOSR5wr\nXoa6UOLc1bP+mvXc+/i9o7r/pjZNVZKWCYlDVZVIoipexlviWmulBoNfs+g1KkuVCdGSIxIbSRkI\nvW3Tbdy57c5RraO1V61NRH98nAoRCltut1x+C99+7NuxbsmlVZDBcSUOqTsdXR184lef4P6994PB\nDRffwGdf/9mKL1Dtd7Wz5dCW0cfnt7P51s3VDjcUcUjShQmsyZoY8AEaGxrpH+xXZV2Nxb6qSiQq\nHV0dXPb1y+g63TV87Js7vsl9u+/j8fc+XtEFKmnjMcXEoVqpsJKuP7eYRP9g9rMq6+JLYxySCpVO\nHtzwuw10n+4edbzndE/FVUVJGo+Js2KVdIU0aB9PanFI4hV2eZSbl7D54OZRM6kBBhms+AI1NOgc\ndVdP0hVruRVKWkuuXqjFIYkXZBXVlQtWYtio4w00BLpADXX1bL51M7evvl1JYxwKW25N1oRhNDVk\n38+qJRdfShySeEEmD66/Zj2ZKZlRx5unNNfFBSpO64EVlguvW7GO37/n96y7ap3Wkoo5dVVJ4gUZ\nrG6d2crj7328bFVVnCf3TSS2wi69P3T+gbsevYtls5dNeHe98So2SL9y4cqaxiDBqRxXEq+a8xLi\nNMeh2rEVm38yJE7PU6IRq61jRcJWzeWy47y96ERjK1fFFKfnKfGnripJhWrNSwhjscVqdX1NNLax\nqpjGeqw4d+FJbSlxiOSp9uS+IKXCYcdWuOhhoXKPVc3nIcmnripJtGpXCVV7cl81u74mGlt+l94V\n865gSuOUiktf49yFJ7WnFockVhjvgqs9uW8i3UvFuoYmGlt+l16Q9aq0X4rkU+KQxApr18By4yVB\n+/nb5rSx7dC2ETvxVdK9VC4pVmvdpiDjQmlYn0uqR11Vkli1fhccdB+Ojq4O7tt936jtW8+ZdM6Y\n3Utx6xpKy/pccZoAmWRKHJJYxbZGDfNdcNCL+YbfbeBE34kRxwzjLZe8Zczupbh1DVWz5DkqSdmA\nKwlqsef4PWZ2xMyeyDs2y8weMLM/5T6fV+K+q8xsj5ntNbOPhB2rJEut3wUHvZgXO99xdh3bNebP\nqnVSrETS1+eKWysuyWrR4vgGsKrg2EeAB919KfBg7vYIZtYIfBW4AWgDbjaztnBDlSSp9bvgoBfz\niVz809I1FCdxa8UlWeiJw90fAp4vOHwj8M3c198E3lLkru3AXnff5+5ngO/m7icyrJbvgoNezCdy\n8a9VUqynPv84tuKSqiZrVZnZYuAn7v6y3O3j7n5u7msDXhi6nXeftwKr3P2/5m6/HVjp7u8f6+dp\nrSoJS9AtV+OwRWspcV6XKwz19nyDStTWse7uZjbh7GVma4A1AIsWLZpwXCLFBF3apBZbtI53KZCw\nypnjShtwVU9UieOwmbW4e6eZtQBHipxzEMh/RRfmjhXl7huBjZBtcVQzWJG4msgkyDj0+VeS9Kq5\nRlYc9lpPg6gSx4+B/wJ8Pvf5R0XO2QIsNbMlZBPGTcDf1SxCCUQL4EWjVKvhL//9L5naNLXsa1Fq\n0cOT/Sfp6OoI/fWrJOlpjax4qkU57neA3wOXmNkBM3sP2YTxRjP7E/CG3G3MbL6ZbQJw937g/cDP\ngV3A99z9ybDjleBUHx+dUq2Gx488PuZrMTR4P7Re1ZBdR3fV5PWrpDxWJbTxVIuqqpvdvcXdJ7n7\nQne/292fc/fr3H2pu7/B3Z/PnXvI3Vfn3XeTu7/U3S9y98+FHauMj/65o1OsUihfqddiqIXYOrOV\nzOSRW+n2e39NXr9KusoeeuahyLvTZLTIB8cl+eLQV16vxloqHUa/FoXdP5XcJwxjrX/V0dXBnmN7\nRt2vyZpUQhsxLTkiE6b6+OgUzve4bO5lNNnI94OFr0VhC7GYWrx+Y81z2fC7DQz4wKj7NTY0aiJk\nxJQ4ZMJKXQBuufyWRE8ui8PkuEpiyJ8E+dO/+ynNU5rLTjost4VsqfuEYaxJjpsPbqZ/sH/U/ZbN\nXqaB8YjVZAJgrWkCYO0VTnS75fJbuOHeGxI72SoOk8XGG8NYkw5v23Qbd267c1QX0bLZy5jWNC02\n8xtKxbn2qrUqqQ1BkAmAShwSiqT/08ch/rBiiENSrERS4kyLRM0cl3RK+oB5HOIPK4akzKBOSpy1\ndPLMAHsO97DzUDfLW5p5+aKiC4uHTolDQpH0HePiEH+lMYxn8mVSZlAnJc4wHOk5xa7ObJLY2dnN\nzkNd7D/2IoO5TqK1r7swssShrioJRdK7GeIQfyUxxCFOmZiBQWf/sV6ePNSdTRSd3ew81M2x3tPD\n5yw4dxrLWzK0zc/Q1pLh0vkZFp43jewasdWhMQ4ljliI88qwlYhD/OMd6E7KWFK96T3dz+7ObnZ1\n5loRnT3sebabU33Z7YUnNRpL5zYPJ4jlLdnPM88pPcmzWpQ4lDikTrTf1c6WQ1tGH5/fzuZbN0cQ\nkQC4O51dp7IJItfVtKuzm6eeO7uV8LnnTBpODpfOz36+aM4MJjcFnCWRyUBPz+jjzc3Q3V3xw2hw\nXKROVGUspkoXnnrVNzDI3iO9I5LEzs5ujp84+5osfsk5LG/J8J9esXA4SbTMnFqdrqZir12541Wg\nxCGSYIVLjoxr8l4EF56k6jrRN5wYhhLF3iO9nBnIdjVNaWpgWUuGG152/nBrYllLhhlT0nWpTdez\nEakzKlkNh7tz4IWTPHloZJI4ePzk8DmzZ0ymbf5MXvPS2bTlxiKWzJ5OU2P6F+TQGIdICBK1P0m5\n7pIUXh8Kneob4E+He9nZ2TVc/rqrs5ue09nlThoMlsyezqXzZw5XNi1vaWZu89SII8+p0uunMQ6R\nCGnzofh6rvd0ruS1a3g84s9HX2QgNzli+uRGlrVkeMvLFwxXNr10XjPTJjdGHHm8KHGIVFm97eUd\nRwODztPPvTg8J2Ko/PVw99m5ES0zp9LWkuH6tvOHk8SiWefQ0FC9uRE10dxcurghJEocIlUWh+VK\nAongwlNNJ870s/vZnhFlr7s7ezjZl12SvanBuHjuDK65+OxYxPKWDOdNnxxx5FUSQeWbEodIlcVh\nuZJAElJy6+4c6Tk9ouR116Fu9j/34nBXfvPUJtpaMtzU3jqcIJZeuoQpXS+MfkCVG49bZInDzC4B\n/k/eoQuBT7r7l/POuRb4EbA/d+gH7v6ZmgUpMg5VKZFNgYkUCPQNDLLv6IsjBqx3dnbz/Itnhs9p\nnTWNtpYMb75y/nCSKLoMR7GkASo3noBYVFWZWSNwEFjp7k/nHb8W+LC7vynI46mqSqIWh+VKohRk\nDa3uU33s7uxh56GuXFdTD3sO93CmPzs3YnJTAy+dN2O4m6lt/kyWtTSTmVrhMhx1XjVWqSRWVV0H\n/Dk/aYgkWT2v6golCgRO9/LpB/+Vv73kQ2fnRnR20/H82bkRs6ZPZnlLM+981WKWtzTT1jKTC+dM\nZ1IdzI1IkrgkjpuA75T43qvM7DGyLZIPu/uTtQtLRMbj4QNbob+V6YNLmDx4IZP9QiYNLuHBR2bw\n4CPbMIMlL5nO5QvP5aZXLsq1JDLMbZ5S1RVfJRyRd1WZ2WTgEHCpux8u+F4GGHT3XjNbDfyLuy8t\n8ThrgDUAixYtuurpp9V4EamFF148k7faa7b8dc/hLtyzrYRBTtFnT9Hf+DRXL17I319/K8vOb+ac\nyTV636quqookanVcM7sReJ+7X1/BuU8BK9z9WLnzNMaRXomakZ0yg4POM8+fGDU3orPr1PA58zJT\nsoPUs2DjY5+id3A3J/0ZJjU2RrdPiBZxrEjSxjhupkQ3lZmdDxx2dzezdqABeK6WwUl8aEb2BAS8\neJ7qG2DPs2c3FdrZ2c3uzm5ePJOdG9HYYFw4ezorl8zKLcGR/Zg9Y8rwY6y9dmM8CgSUHKou0sRh\nZtOBNwJr846tA3D3O4C3Au81s37gJHCTR91EkshoRvYElFkBN3+L0qFWxL6jvcNblM6Y0sTylmbe\netXC3AzrmSy97EKmHn9+9OPlJaJ6LxBIs0gTh7u/CLyk4NgdeV9/BfhKreNKjZQ10RM3IzsME3hN\nB6yB/bPm8+TcC9k1dwk7517IzrkXcuxzDw6fM7RF6erLWobLXxeeN230MhzFkgZobkSdiENXlYQl\nZfssJG5GdhgqfE17T/ez59m8jYXe/iX2zLmAU5OyK7pOGuhj6bFnuHb/VpZ/9APDSaIWW5RK8ilx\nSGJoRvZoDnQ2z862IB78U+ktSs+c4m3bf8byI/toO7yfi5/rYPJgdtlwfvrl4g8uUkLkVVVhUFVV\nTgrLEOt5RnbfwCB7Wy5iZ35X07wlHJ+WGT5naIvStuF9I3JblDaUmUA3nr+FFP5t1btEleOGQYkj\nR//c4xZ12e/QFqVDg9W7Orv50+G8LUr7TnPJsadpO7KftsP7aDuyj0v27qC51DIc1R7v0t9WcDEf\nc1TiUOLI0j/3uARZZ2miCrcoHapsGrlF6ZTs8hvzM7R9aB1tR/az5PmDNPlg4YNVNbayYn4RjKWY\n/z8mbR6HhCXh+yxEJayy36EtSnd1jkwShVuUvnzRudxy9QXFtyj92z/E4zVVcqhrShxppn/ucalG\n2e9zvafPdjUV2aL0nMmNLG/JcOPL57O8JcOl82dySSVblOo1lRhQ4hApEKTsN+gWpdkkUcEWpWno\nCkrDc5CiNMYhsRH1gHR+HMXGOB5+9x/oPZkZkSD2PNvDiTMjtyjNr2ha3pJh1ni2KI15f3hF0vAc\nqinmv4+qDY7nVqed4+5/Ljh+ubs/NrEww6PEkTy1HJAei7uz/eB+/uH//Rs7D3WRaWyjceACDrxw\nZsQWpUOth6FEcfHcGUxpGqOrqVJBLzJxfHcf8wtlzcXxNcpTlcFxM/sb4MvAETObBLzT3bfkvv0N\n4BUTDVRkSFTrUPUPDLLv2IsjWhE7D3Xz3ItngOz/0HmzprH8/Ax//YqzSWLBuUW2KI1SylYJSKUY\nJIdqKTfG8THgKnfvzK1M+29m9lF3/yEQo/8YSYNarEOVv0Xprs7syq+FW5ReMq+ZNyyflyt/LbNF\naczfPUYukxn7HEmscomj0d07Adz9ETN7PfATM2slu9KBSNVUcx0qd+fg8ZPDK77u7OwqukVpW0tm\n/FuU6h1+efo9pFq5xNFjZhcNjW/kWh7XAvcBl9YiOKkf412H6kz/IH86MrQkeE82SRzqpvtUdm5E\n4Raly1uauXT+zPhvUZrmOThpeA51rlziWEdBl5S795jZKuCjoUYldad1Zis71u0ouw5VsS1K9x7p\npT83N2LapEaWtTTzpivmD49F1HSL0mpKc3dXrZ6buhNDU7Kqysz2AXcAX3L3gdyxecCXgGWVjr5H\nQVVVyTY46HS8cOLskuC5getDeVuUzm2eMlzVtDyXJBa/ZDqN5eZGVFPcKobidpGMw+8nDjEkSLWW\nHLkK+Adgu5l9ALgM+B/ABuAdE45SBDh5ZoA9h3uGZ1jvys22zt+i9KI503nlklkj5kfkb1Eq6B20\n1FTJxOHuLwDrcknjl8Ah4Gp3P1Cr4CRdjvacHjXDutQWpUPLcCydN4Opk6o0N6Ka0jwGUQ36/aRa\nuXkc5wL/CKwEVgGrgfvN7APu/qsaxScJNDDo7D/Wy86CfayP9pxdhmPkFqXZqqaiW5TGld7hl6ff\nT6qV66p6FPga8D537wd+YWZXAl8zs6fd/eaJ/nAzewroAQaA/sL+NcuWvfwL2aR1guwkxEcn+nOl\nekZtUdrZw55nuznVl50bManRWDq3mde9dA5tuSU4tEWpjFstxnLiNl4UQ+USx2sLu6XcfTvwKjO7\ntYoxvN7dj5X43g3A0tzHSuDruc9SY+5OZ9eps2MRuWSRv0XpzGmTaGvJ8LaVFwyPR1w0ZwaTmyqc\nGyH1Y7wX5yDzZ8bbXaY5OmMqN8ZRcizD3e8KJ5xRbgS+5dnSr4fN7FwzaxmamCjh6BsYZO+R3pHL\ncHR2c/zE2cl5Q1uU/vUrFg5XNbXMnBrvuRESH7W4OKt1EJqoC9wd+KWZDQB3uvvGgu8vADrybh/I\nHRuVOMxsDbAGYNGiReFEm0JdJ/tG7BkxNDdieIvSpgaWnd/MqkvPz+5A15JhWUuGGVOi/tNJAHV5\nSEpF/d//anc/aGZzgQfMbLe7PzSeB8olnY2QncdRzSDTwN3peP7kcOthKFmM3KJ0MstbMrzmpYuz\nXU0tGZbMnk5TpctwhCHJF191eUhKRZo43P1g7vMRM/sh0A7kJ46DQP6a2gtzx6SMoS1Kd3Z2Da/X\nVGyL0ldccB63XH3B8H7WI7YojQtdfEViJ7LEYWbTgYbcMibTgeuBzxSc9mPg/Wb2XbKD4l0a3xjp\nud7Tw2s0DSWJvUd7i25R2tYyk7b5mcq2KBWJo1rMD9EclDFF2eKYB/wwN5jaBPy7u//MzNYBuPsd\nwCaypbh7yZbjviuiWCNXuEXpUHdT/hal52emcun8DG9smzc8w/qCsbYolWR3hyXVeC/OtXg99JqP\nKbLE4e77gCuKHL8j72sH3lfLuOLgxJl+dj/bM2LQutgWpa+6aPbwDnTLWzKcN54tSkXdYVHQxTnR\noh4cr3tdJ/t49JkXRpS+7j/24ogtSttaMvzNitbhqqal86q4RamER10eklJKHBHb+tTzvOeb2ZV8\nW2dNo60lw5uvmD+88mvstiittSRffPWuWlJKiSNir1wyi++t/Q+ltyitd0m9+GrcRFJMiSNimamT\naF8yK+owpNo0biIppkWEREQkECUOEREJRIlDREQCUeIQEZFAlDhEwlCqXLhWZcSZDJiN/shkavPz\nJdVUVSUShqhLblXVJSFSi0OkWq0DvcuXOqHEIdLdDe6jP4K2GvQuvzJxTLBxjCnGlDhEpLbimGDj\nGFOMKXGIiEggShwiaRR1VZekmhKHSNTC6F+v1riNSBFKHCLVMt53+epfl4RR4pDiVGUSXBjv8uP4\n+5/o30Ycu9HiGFOMRZY4zKzVzH5tZjvN7Ekz+0CRc641sy4z2577+GQUsdYlvQuOp1r9/sslh4n+\nbcSxGy2OMcVYlDPH+4EPufujZtYMbDOzB9x9Z8F5v3H3N0UQn0j90hsHKSOyFoe7d7r7o7mve4Bd\nwIKo4hERkcrEYozDzBYDLwc2F/n2q8zsMTO738wurWlgIrWgfnRJmMgTh5nNAL4PfNDdCzsUHwUW\nufvlwO3AfWUeZ42ZbTWzrUePHg0vYJFqK9a/Xq9UlJEIkSYOM5tENmnc6+4/KPy+u3e7e2/u603A\nJDObXeyx3H2ju69w9xVz5swJNe66oCqTaMX59x9mbBpbSYTIBsfNzIC7gV3u/k8lzjkfOOzubmbt\nZBPdczUMs36pmiRaUf/+m5uLX6ybm6OPTSIXZVXVNcDbgcfNbHvu2MeARQDufgfwVuC9ZtYPnARu\ncq/ndrxIlZQqqx1KDEoOUkZkicPdfwvYGOd8BfhKbSISqSPqEpIJiHxwXEREkkWJQ9JHlTnJFeei\nABmmxCHpo26Y2qtWstbSH4mgxCEiE6dkXVeUOETqkbqEZAKiLMcVkaio60cmQC0OkXI00C4yihKH\npE81u2HUdy8yirqqJH3UDVN75ZYokdRRi0MkaeLYfaYy2rqixCGSNOo+k4gpcYiISCBKHCLlaL6D\nyChKHCLlqO++uuI4PiOBKXFIMqTtgpO251Mpjc+kghKHJEPaLjgTeT7qPpOIaR6HSNKom0wiphaH\njFSvXSgiUrFIE4eZrTKzPWa218w+UuT7Zmb/mvv+Y2b2iijirCtp6xJKEyV1iYnIEoeZNQJfBW4A\n2oCbzayt4LQbgKW5jzXA12sapFSfLn7jl4akrvGZVIiyxdEO7HX3fe5+BvgucGPBOTcC3/Ksh4Fz\nzayl1oFKFY334pe2C07ank+lVN6cClEOji8AOvJuHwBWVnDOAqAz3NAkdtJ2YUnb85G6kprBcTNb\nY2ZbzWzr0aNHow5HRCS1okwcB4HWvNsLc8eCngOAu2909xXuvmLOnDlVDbSu1GsXiohULMrEsQVY\namZLzGwycBPw44Jzfgy8I1dddTXQ5e7qpgqT+qDjS0ldYiKyMQ537zez9wM/BxqBe9z9STNbl/v+\nHcAmYDWwFzgBvCuqeGWCMpnyA+C6+I1NyVtiItKZ4+6+iWxyyD92R97XDryv1nFJCMolDffaxSEi\nE5aawXGR1NMcGIkJJQ6RpEjDBEBJBSUOEREJRIlDREQCUeKQ2lApqUhqaD8OqQ2VkoqkhlocIkmh\nVpvEhFocIkmhVpvEhFocIqA5EiIBKHGIgOZIiASgxAF6tynh0d+WpJASB+jdZr0L8yKuvy1JISUO\nEV3ERQJR4hARkUCUOETK0RwJkVGUOETK0dwJkVGUOEAzcqW0iVZF6W9LUkgzx0HvKutdc3PxAfJS\nx6HyAXX9bUkKqcUhyRDmfIju7uz2tYUfuuiLFBVJi8PMvgD8R+AM8GfgXe5+vMh5TwE9wADQ7+4r\nahmnxIjmQ4jERlQtjgeAl7n75cAfgY+WOff17n6lkoaISDxEkjjc/Rfu3p+7+TCwMIo4REQkuDiM\ncbwbuL/E9xz4pZltM7M15R7EzNaY2VYz23r06NGqByl1SlVRIqOENsZhZr8Ezi/yrY+7+49y53wc\n6AfuLfEwr3b3g2Y2F3jAzHa7+0PFTnT3jcBGgBUrVviEn4AIaIBcpIjQEoe7v6Hc983sncCbgOvc\nveiF3t0P5j4fMbMfAu1A0cQhKVeuZFZEaiqSriozWwWsB97s7idKnDPdzJqHvgauB56oXZQSKyqZ\nFYmNqMYi/YY5AAAE60lEQVQ4vgI0k+1+2m5mdwCY2Xwz25Q7Zx7wWzPbATwC/NTdfxZNuCIiMiSS\neRzufnGJ44eA1bmv9wFX1DIuSZFMpnTXllopIhMSh6oqkerThEGR0ChxiIhIIEocIiISiBKHiIgE\nosQhIiKBKHFIOmmpEJHQaCMnSSeV3IqERi0OEREJRIlDREQCUeIQEZFAlDhERCQQJQ4REQnESmyF\nkWhmdhR4Ouo4ApgNHIs6iHFQ3LWTxJhBcdfSRGO+wN3nVHJiKhNH0pjZVndfEXUcQSnu2klizKC4\na6mWMaurSkREAlHiEBGRQJQ44mFj1AGMk+KunSTGDIq7lmoWs8Y4REQkELU4REQkECWOmDCzz5rZ\nY2a23cx+YWbzo46pEmb2BTPbnYv9h2Z2btQxjcXM/rOZPWlmg2YW+8oZM1tlZnvMbK+ZfSTqeCph\nZveY2REzeyLqWCplZq1m9msz25n7+/hA1DFVwsymmtkjZrYjF/ffh/4z1VUVD2aWcffu3Nf/DWhz\n93URhzUmM7se+JW795vZPwK4+/+KOKyyzGw5MAjcCXzY3bdGHFJJZtYI/BF4I3AA2ALc7O47Iw1s\nDGb2WqAX+Ja7vyzqeCphZi1Ai7s/ambNwDbgLQn4XRsw3d17zWwS8FvgA+7+cFg/Uy2OmBhKGjnT\ngURkdHf/hbv3524+DCyMMp5KuPsud98TdRwVagf2uvs+dz8DfBe4MeKYxuTuDwHPRx1HEO7e6e6P\n5r7uAXYBC6KNamye1Zu7OSn3Eer1Q4kjRszsc2bWAbwN+GTU8YzDu4H7ow4iZRYAHXm3D5CAi1nS\nmdli4OXA5mgjqYyZNZrZduAI8IC7hxq3EkcNmdkvzeyJIh83Arj7x929FbgXeH+00Z41Vty5cz4O\n9JONPXKVxCxSjJnNAL4PfLCgJyC23H3A3a8k2+JvN7NQuwe1A2ANufsbKjz1XmAT8KkQw6nYWHGb\n2TuBNwHXeUwGzQL8ruPuINCad3th7piEIDdG8H3gXnf/QdTxBOXux83s18AqILTCBLU4YsLMlubd\nvBHYHVUsQZjZKmA98GZ3PxF1PCm0BVhqZkvMbDJwE/DjiGNKpdwg893ALnf/p6jjqZSZzRmqZjSz\naWQLKUK9fqiqKibM7PvAJWSrfZ4G1rl77N9ZmtleYArwXO7Qw3GvBjOzvwJuB+YAx4Ht7v4X0UZV\nmpmtBr4MNAL3uPvnIg5pTGb2HeBasiu2HgY+5e53RxrUGMzs1cBvgMfJ/h8CfMzdN0UX1djM7HLg\nm2T/PhqA77n7Z0L9mUocIiIShLqqREQkECUOEREJRIlDREQCUeIQEZFAlDhERCQQJQ6REORWWt1v\nZrNyt8/L3V5sZj8zs+Nm9pOo4xQZDyUOkRC4ewfwdeDzuUOfBza6+1PAF4C3RxSayIQpcYiE55+B\nq83sg8CrgS8CuPuDQE+UgYlMhNaqEgmJu/eZ2f8EfgZc7+59UcckUg1qcYiE6wagE0jEZkYilVDi\nEAmJmV1JdsG5q4H/ntthTiTxlDhEQpBbafXrZPd0eIbsgPgXo41KpDqUOETCcSvwjLs/kLv9NWC5\nmb3OzH4D/F/gOjM7YGaxXZlXpBitjisiIoGoxSEiIoEocYiISCBKHCIiEogSh4iIBKLEISIigShx\niIhIIEocIiISiBKHiIgE8v8Bsop6nrlyQAkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x154a6f19dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotBestFit(weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.2.1.随机梯度上升"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def stocGradAscent0(dataMatrix, classLabels):\n",
    "    \"\"\"\n",
    "    随机梯度上升\n",
    "    参数：\n",
    "        dataMatrix -- 数据矩阵\n",
    "        classLabels -- 类别标签\n",
    "    返回：\n",
    "        weights -- 训练后的权重参数\n",
    "    \"\"\"\n",
    "    #确保标签向量为列向量\n",
    "    classLabels = np.array(classLabels).reshape(-1, 1)\n",
    "    #求矩阵维度\n",
    "    m,n = np.shape(dataMatrix)\n",
    "    #学习率\n",
    "    alpha = 0.01\n",
    "    #初始化为全1\n",
    "    weights = np.ones((n, 1))\n",
    "    #遍历每个数据\n",
    "    for i in range(m):\n",
    "        h = sigmoid(np.dot(dataMatrix[i:i+1, :], weights))\n",
    "        error = classLabels[i] - h\n",
    "        weights = weights + alpha * dataMatrix[i:i+1, :].T * error\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.01702007]\n",
      " [ 0.85914348]\n",
      " [-0.36579921]]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nN1OCj0FhD1sAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x154a73c00f0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dataArr, labelMat = loadDataSet()\n",
    "weights0 = stocGradAscent0(np.array(dataArr), labelMat)\n",
    "print(weights0)\n",
    "plotBestFit(weights0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.2.2.改进的随机梯度上升算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def stocGradAscent1(dataMatrix, classLabels, numIter=150):\n",
    "    \"\"\"\n",
    "    改进的随机梯度上升算法\n",
    "    参数：\n",
    "        dataMatrix -- 数据矩阵\n",
    "        classLabels -- 标签\n",
    "        numIter -- 迭代次数\n",
    "    返回：\n",
    "        weights -- 训练后的权重参数\n",
    "    \"\"\"\n",
    "    classLabels = np.array(classLabels).reshape(-1, 1)\n",
    "    m,n = np.shape(dataMatrix)\n",
    "    weights = np.ones((n, 1))\n",
    "    for j in range(numIter):\n",
    "        dataIndex = list(range(m))\n",
    "        for i in range(m):\n",
    "            #学习率随迭代的进行而变化\n",
    "            alpha = 4/(1.0+j+i)+0.0001\n",
    "            #随机的参数\n",
    "            randIndex = np.int(np.random.uniform(0,len(dataIndex)))\n",
    "            h = sigmoid(np.dot(dataMatrix[randIndex:randIndex+1, :], weights))\n",
    "            error = classLabels[randIndex:randIndex+1, 0] - h\n",
    "            weights = weights + alpha * error * dataMatrix[randIndex:randIndex+1, :].T\n",
    "            del(dataIndex[randIndex])\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 13.21735665]\n",
      " [  1.07914686]\n",
      " [ -1.91868707]]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x154a67354e0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dataArr, labelMat = loadDataSet()\n",
    "weights1 = stocGradAscent1(np.array(dataArr), labelMat)\n",
    "print(weights1)\n",
    "plotBestFit(weights1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.3.示例：从疝气病症预测病马的死亡率 \n",
    "### 5.3.1.用 Logistic回归进行分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def classifyVector(inX, weights):\n",
    "    \"\"\"\n",
    "    对输入的向量做预测\n",
    "    参数：\n",
    "        inX -- 输入向量\n",
    "        weights -- 权重参数\n",
    "    \"\"\"\n",
    "    prob = sigmoid(np.sum(inX*weights))\n",
    "    if prob > 0.5: return 1.0\n",
    "    else: return 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def colicTest():\n",
    "    \"\"\"\n",
    "    实例的测试函数\n",
    "    参数：\n",
    "        无\n",
    "    返回：\n",
    "        errorRate -- 测试得到的错误率\n",
    "    \"\"\"\n",
    "    #读取训练集和测试集的数据\n",
    "    frTrain = open('horseColicTraining.txt'); frTest = open('horseColicTest.txt')\n",
    "    trainingSet = []; trainingLabels = []\n",
    "    for line in frTrain.readlines():\n",
    "        currLine = line.strip().split('\\t')\n",
    "        lineArr =[]\n",
    "        for i in range(21):\n",
    "            lineArr.append(np.float(currLine[i]))\n",
    "        trainingSet.append(lineArr)\n",
    "        trainingLabels.append(np.float(currLine[21]))\n",
    "    trainWeights = stocGradAscent1(np.array(trainingSet), trainingLabels, 1000)\n",
    "    errorCount = 0; numTestVec = 0.0\n",
    "    for line in frTest.readlines():\n",
    "        numTestVec += 1.0\n",
    "        currLine = line.strip().split('\\t')\n",
    "        lineArr =[]\n",
    "        for i in range(21):\n",
    "            lineArr.append(np.float(currLine[i]))\n",
    "        if np.int(classifyVector(np.array(lineArr), trainWeights))!= np.int(currLine[21]):\n",
    "            errorCount += 1\n",
    "    errorRate = (np.float(errorCount)/numTestVec)\n",
    "    print(\"the error rate of this test is:{}\".format(errorRate))\n",
    "    return errorRate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def multiTest():\n",
    "    \"\"\"\n",
    "    多次调用测试函数，并取平均\n",
    "    参数：\n",
    "        无\n",
    "    返回：\n",
    "        无 -- 直接打印结果\n",
    "    \"\"\"\n",
    "    numTests = 10; errorSum=0.0\n",
    "    for k in range(numTests):\n",
    "        errorSum += colicTest()\n",
    "    print(\"after {} iterations the average error rate is: {}\".format(numTests, errorSum/np.float(numTests)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "F:\\Anaconda\\lib\\site-packages\\ipykernel_launcher.py:2: RuntimeWarning: overflow encountered in exp\n",
      "  \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "the error rate of this test is:0.29850746268656714\n",
      "after 10 iterations the average error rate is: 0.29850746268656714\n"
     ]
    }
   ],
   "source": [
    "multiTest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
